package com.kedll.library.util;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Build;
import android.os.Environment;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import com.kedll.library.KBaseApplication;
import com.kedll.library.R;
import com.kedll.library.receiver.ActivitiesManager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//import com.umeng.analytics.MobclickAgent;

//import com.tencent.android.tpush.XGPushConfig;

/**
 * Created by yangweirong on 14/12/13.
 */
public class SystemUtils {

    public static final Context appContext = KBaseApplication.instance;

    public static final String TAG = SystemUtils.class.getSimpleName();

    /**
     * FlyMe版本号
     */
    public static final String FLY_ME_VERSION = getFlyMeVersion();
    /**
     * 云OS版本号
     */
    public static final String YUN_OS_VERSION = getYunOSVersion();

    /**
     * 小米特别处理
     */
    public static final String MIUI_VERSION = SystemUtils.getMiuiVersion();

    public static final long FIRST_INSTALL_TIME = SystemUtils.getFirstInstallTime();

    public static final long LAST_UPDATE_TIME = SystemUtils.getLastUpdateTime();


    public static boolean isYunOS() {
        return StringUtil.isNotEmpty(YUN_OS_VERSION);
    }

    /**
     * @return
     */
    public static boolean isMiui() {
        return StringUtil.isNotEmpty(SystemUtils.MIUI_VERSION);
    }

    public static boolean isFlyMe() {
        return StringUtil.isNotEmpty(SystemUtils.FLY_ME_VERSION);
    }

    public static String getYunOSVersion() {
        return getSystemProperty("ro.yunos.version");
    }

    /**
     * 判断是否flyme，并返回版本号
     *
     * @return
     */
    public static String getFlyMeVersion() {
        String display = getSystemProperty("ro.build.version.incremental");
        Pattern p = Pattern.compile("Flyme_OS_([\\d\\.]+)");
        Matcher m = p.matcher(display);
        String version = "";
        if (m.find()) {
            version = m.group(1);
        }
        return version;
    }

    public static String getApplicationName() {
        PackageManager packageManager = null;
        ApplicationInfo applicationInfo = null;
        try {
            packageManager = appContext.getPackageManager();
            applicationInfo = packageManager.getApplicationInfo(appContext.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            applicationInfo = null;
        }
        String applicationName = (String) packageManager.getApplicationLabel(applicationInfo);
        return applicationName;
    }

    public static String getMiuiVersion() {
        return getSystemProperty("ro.miui.ui.version.name");
    }


    /**
     * 返回状态栏的高度
     *
     * @param ctx
     * @return
     */
    public static int getStatusBarHeight(Context ctx) {
        int result = 0;
        int resourceId = ctx.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = ctx.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    /**
     * 获取底部导航栏高度
     *
     * @param ctx
     * @return
     */
    public static int getNavigationBarHeight(Context ctx) {
        Resources resources = ctx.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        int height = 0;
        if (resourceId > 0) {
            height = resources.getDimensionPixelSize(resourceId);
        }
        return height;
    }

    public static void setViewTop(Context ctx, View view) {
        int stHeight = SystemUtils.getStatusBarHeight(ctx);
        ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        params.setMargins(0, stHeight, 0, 0);
        view.setLayoutParams(params);
    }

    /**
     * 判断是否存在魅族的SmartBar
     *
     * @return
     */
    public static boolean hasMeiZuSmartBar() {
        try {
            // 可用反射调用Build.hasSmartBar()
            Method method = Class.forName("android.os.Build").getMethod("hasSmartBar");
            return ((Boolean) method.invoke(null)).booleanValue();
        } catch (Exception e) {
        }

        if (Build.DEVICE.equals("mx2")) {
            return true;
        } else if (Build.DEVICE.equals("mx") ||
                Build.DEVICE.equals("m9")) {
            return false;
        }
        return false;
    }

    public static String getDataDir() {
        return appContext.getFilesDir().getParent() + "/";
    }

    public static boolean canReadExternalStorage() {
        String state = Environment.getExternalStorageState();
        return state.equals(Environment.MEDIA_MOUNTED) || state.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
    }

    public static boolean canWriteExternalStorage() {
        String state = Environment.getExternalStorageState();
        return state.equals(Environment.MEDIA_MOUNTED);
    }

    public static String getDeviceId() {
        return MyUtils.getDeviceId(KBaseApplication.getInstance());
    }

    public static int getMyVersionCode(Context ctx) {
        try {
            return ctx.getPackageManager().getPackageInfo(
                    ctx.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "error", e);
            return 1;
        }
    }

    public static int getMyVersionCode() {
        return getMyVersionCode(appContext);
    }

    /**
     * 获取系统记录的首次安装时间
     *
     * @return
     */
    public static long getFirstInstallTime() {
        try {
            return appContext.getPackageManager().getPackageInfo(appContext.getPackageName(), 0).firstInstallTime;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "error", e);
            return 0;
        }
    }

    /**
     * 获取上次更新时间
     *
     * @return
     */
    public static long getLastUpdateTime() {
        try {
            return appContext.getPackageManager().getPackageInfo(appContext.getPackageName(), 0).lastUpdateTime;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "error", e);
            return 0;
        }
    }

    public static String getMyPackageName() {
        return appContext.getPackageName();
    }

    public static String getMyVersion() {
        return getMyVersion(appContext);
    }

    public static String getMyVersion(Context ctx) {
        try {
            PackageManager packageManager = ctx.getPackageManager();
            // getPackageName()是你当前类的包名，0代表是获取版本信息
            PackageInfo packInfo = packageManager.getPackageInfo(ctx.getPackageName(), 0);
            return packInfo.versionName;
        } catch (Exception e) {
//            MobclickAgent.reportError(ctx, e);
        }
        return "";
    }


    private static long serviceBootTime = -1;

    /**
     * 获取服务运行时间
     *
     * @return
     */
    public static long getServiceBootTime() {
        return serviceBootTime;
    }

    public static void setServiceBootTime(long sbt) {
        serviceBootTime = sbt;
    }

    public static void restartSelf() {
        Intent intent = appContext.getPackageManager().getLaunchIntentForPackage(appContext.getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        appContext.startActivity(intent);
        ActivitiesManager.getInstance().exit();
    }

    /**
     * 服务运行时间
     *
     * @return
     */
    public static long serviceElapsedTime() {
        if (serviceBootTime < 0) {
            return -1;
        }
        return System.currentTimeMillis() - serviceBootTime;
    }

    public static String getSystemProperty(String propName) {
        String line = "";
        BufferedReader reader = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop " + propName);
            reader = new BufferedReader(new InputStreamReader(p.getInputStream()), 512);
            line = reader.readLine();
        } catch (IOException ex) {
            Log.e(TAG, "Unable to read system property " + propName, ex);
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (Exception e) {
                //ignore
            }
        }
        return line;
    }

    public static Map<String, String> getSystemProperties() {
        Map<String, String> map = new HashMap<String, String>();
        BufferedReader reader = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop");
            reader = new BufferedReader(new InputStreamReader(p.getInputStream()), 5120);
            String line = reader.readLine();
            while (line != null) {
                Pattern pattern = Pattern.compile("\\[(.+)\\]\\s*:\\s*\\[(.+)\\]");
                Matcher m = pattern.matcher(line);
                if (m.find()) {
                    String key = m.group(1);
                    String value = m.group(2);
                    map.put(key, value);
                }
                line = reader.readLine();
            }
        } catch (IOException ex) {
            Log.e(TAG, "Unable to read system properties.", ex);
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (Exception e) {
                //ignore
            }
        }
        return map;
    }

    public static void appendValue(Context context, SpannableStringBuilder builder, int span, String str) {
        appendValue(builder, span, str, (int) context.getResources().getDimension(R.dimen.gen_title_size));
    }

    public static void appendValue(SpannableStringBuilder builder, int span, String str, int fontSize) {
        appendValue(builder, span, str, fontSize, -1);
    }

    public static void appendValue(SpannableStringBuilder builder, String str, int span, int color) {
        appendValue(builder, span, str, -1, color);
    }

    public static void appendValue(SpannableStringBuilder builder, int span, String str, int fontSize, int color) {
        int size = builder.length();
        builder.append(str);
        if (fontSize != -1) {
            builder.setSpan(new AbsoluteSizeSpan(fontSize), size, size + span, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        }
        if (color != -1) {
            builder.setSpan(new ForegroundColorSpan(color), size, size + span, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        }
    }

    public static String getSystemProperty2(String s) {
        String s1;
        try {
            s1 = Class.forName("android.os.SystemProperties").getMethod("get", new Class[]{String.class}).invoke(null, new Object[]{
                    s
            }).toString();
        } catch (Exception exception) {
            Log.e("SystemUtils", exception);
            return null;
        }
        return s1;
    }

    public static Map<String, String> dumpSystemInfo() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("Version", getMyVersion(appContext));
        map.put("VersionCode", String.valueOf(getMyVersionCode(appContext)));
        map.put("Auid", MyUtils.getDeviceId(KBaseApplication.getInstance()));
//        map.put("DeviceId", XGPushConfig.getToken(appContext));
        map.put("MIUI", getMiuiVersion());
        map.put("FlyMe", getFlyMeVersion());
        map.put("YunOS", getYunOSVersion());
        map.put("CPU_ABI", Build.CPU_ABI);
        map.put("TAGS", Build.TAGS);
        map.put("MODEL", Build.MODEL);
        map.put("SDK", String.valueOf(Build.VERSION.SDK_INT));
        map.put("DEVICE", Build.DEVICE);
        map.put("DISPLAY", Build.DISPLAY);
        map.put("BRAND", Build.BRAND);
        map.put("BOARD", Build.BOARD);
        map.put("ID", Build.ID);
        map.put("MANUFACTURER", Build.MANUFACTURER);
        map.put("FINGERPRINT", Build.FINGERPRINT);
        map.put("TYPE", Build.TYPE);
        map.put("HARDWARE", Build.HARDWARE);
        map.put("SERIAL", Build.SERIAL);
        map.put("TIME", String.valueOf(Build.TIME));
        map.put("USER", Build.USER);
        map.put("HOST", Build.HOST);
        map.put("VERSION.INCREMENTAL", Build.VERSION.INCREMENTAL);
        map.put("VERSION.RELEASE", Build.VERSION.RELEASE);
        map.put("VERSION.CODENAME", Build.VERSION.CODENAME);
        map.put("VERSION_CODES.BASE", String.valueOf(Build.VERSION_CODES.BASE));
        map.put("PKG_FIRST_INSTALL_TIME", DateUtil.simpleFormat(SystemUtils.getFirstInstallTime()));
        map.put("PKG_LAST_UPDATE_TIME", DateUtil.simpleFormat(SystemUtils.getLastUpdateTime()));
        return map;
    }

    /**
     * 设备制造商，例如 XiaoMi
     *
     * @return
     */
    public static String getManufacture() {
        return Build.MANUFACTURER;
    }

    /**
     * 手机设备型号，例如 MI2
     *
     * @return
     */
    public static String getDeviceModel() {
        return Build.MODEL;
    }

    public static String getDevice() {
        return Build.DEVICE;
    }

    public static String getDeviceBrand() {
        return Build.BRAND;
    }

    public static String getDisplay() {
        return Build.DISPLAY;
    }

    /**
     * 操作系统版本，例如 4.4.4
     *
     * @return
     */
    public static String getOSVersion() {
        return Build.VERSION.RELEASE;
    }

    public static int getSDKInt() {
        return Build.VERSION.SDK_INT;
    }

    public static String getTimeZone() {
        return TimeZone.getDefault().getID();
    }

    public static String getCountry() {
        return Locale.getDefault().getCountry();
    }

    public static String getLanguage() {
        return Locale.getDefault().getLanguage();
    }

    public static Context getContext() {
        Context ac = ActivitiesManager.getInstance().currentActivity();
        return ac != null ? ac : appContext;
    }


    public static boolean isTopRunningApp(Context ctx) {
        ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        String pkgName = "";
        try {
            //处理android 5.0和云os版本不能获取的bug
            if (Build.VERSION.SDK_INT >= 21 || isYunOS()) {
                pkgName = getTopRunningAppForL(am, ctx);
            } else {
                ActivityManager.RunningTaskInfo taskInfo = am.getRunningTasks(1).get(0);
                pkgName = taskInfo.topActivity.getPackageName();//获取当前在前台的应用;
            }
        } catch (Exception e) {
            Exception ex = new Exception("failed to get top running app", e);
            Log.e(TAG, ex.getMessage(), ex);
//            MobclickAgent.reportError(ctx, ex);
        }
        return StringUtil.isEqual(pkgName, getMyPackageName());
    }

    public static String getTopRunningAppForL(ActivityManager am, Context ctx) {
        List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
        List<String> runningApps = new ArrayList<String>(processInfos.size());
        for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
            if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                runningApps.addAll(Arrays.asList(processInfo.pkgList));
            }
        }
        Log.v(TAG, "Current running processes: " + TextUtils.join(", ", runningApps));
        if (runningApps.size() > 0)
            return runningApps.get(0);
        return "";
    }


    /**
     * 判断服务是否正在运行
     *
     * @param context
     * @param className 判断的服务名字：包名+类名
     * @return true在运行 false 不在运行
     */
    public static boolean isServiceRunning(Context context, String className) {
        boolean isRunning = false;
        ActivityManager activityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        //获取所有的服务
        List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
        if (services != null && services.size() > 0) {
            for (ActivityManager.RunningServiceInfo service : services) {
                if (className.equals(service.service.getClassName())) {
                    isRunning = true;
                    break;
                }
            }
        }
        return isRunning;
    }

    /**
     * 修改MIUI
     *
     * @param activity
     * @param darkmode
     * @return
     */
    public static boolean setMiuiStatusBarDarkMode(Activity activity, boolean darkmode) {
        Class<? extends Window> clazz = activity.getWindow().getClass();
        try {
            int darkModeFlag = 0;
            Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
            Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
            darkModeFlag = field.getInt(layoutParams);
            Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
            extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 修改过FlyMe
     *
     * @param activity
     * @param dark
     * @return
     */
    public static boolean setMeizuStatusBarDarkIcon(Activity activity, boolean dark) {
        boolean result = false;
        if (activity != null) {
            try {
                WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
                Field darkFlag = WindowManager.LayoutParams.class
                        .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
                Field meizuFlags = WindowManager.LayoutParams.class
                        .getDeclaredField("meizuFlags");
                darkFlag.setAccessible(true);
                meizuFlags.setAccessible(true);
                int bit = darkFlag.getInt(null);
                int value = meizuFlags.getInt(lp);
                if (dark) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                activity.getWindow().setAttributes(lp);
                result = true;
            } catch (Exception e) {
            }
        }
        return result;
    }
}
